﻿using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Threading.Tasks;

namespace BattleNet.D3
{
    /// <summary>
    /// 
    /// </summary>
    public class D3ServiceClient : ClientBase<ID3Service>, ID3Service, IDisposable
    {
        #region Member/Properties

        /// <summary>
        /// 
        /// </summary>
        private bool disposed = false;

        #region Region

        /// <summary>
        /// 
        /// </summary>
        private Regions _region;
        /// <summary>
        /// 
        /// </summary>
        public virtual Regions Region
        {
            get { return this._region; }
        }

        #endregion

        #region Localization

        /// <summary>
        /// 
        /// </summary>
        private Localizations _localization;
        /// <summary>
        /// 
        /// </summary>
        public virtual Localizations Localization
        {
            get { return this._localization; }
        }

        #endregion

        #endregion

        #region Constructor/Deconstructor

        /// <summary>
        /// 
        /// </summary>
        public D3ServiceClient(Regions region, Localizations localization)
            : base(new WebHttpBinding(), new EndpointAddress(BattleNet.GetBaseUriByRegion(region)))
        {
            this._region = region;
            this._localization = localization;

            /// NET 4 
            /// this.Endpoint.Behaviors.Add(new WebHttpBehavior());
            /// NET 4.5
            this.Endpoint.EndpointBehaviors.Add(new WebHttpBehavior());

            ((WebHttpBinding)this.Endpoint.Binding).MaxReceivedMessageSize = 524288;
        }

        /// <summary>
        /// 
        /// </summary>
        ~D3ServiceClient()      
        {
            Dispose(false);
        }

        #endregion

        #region IDisposable - Implementation

        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="disposing"></param>
        private void Dispose(bool disposing)
        {
            if(!this.disposed)
            {
                if(disposing)
                {
                }

                this.InnerChannel.Close();
                this.ChannelFactory.Close();
                this.Close();
            }
            disposed = true;         
        }

        #endregion

        #region ID3Service - Implementation

        #region GetProfile 

        /// <summary>
        /// 
        /// </summary>
        /// <param name="battletagName"></param>
        /// <param name="battletagCode"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        Profile ID3Service.GetProfile(string battletagName, string battletagCode, string localization)
        {
            return base.Channel.GetProfile(battletagName, battletagCode, localization);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="battletagName"></param>
        /// <param name="battletagCode"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        Task<Profile> ID3Service.GetProfileAsync(string battletagName, string battletagCode, string localization)
        {
            return base.Channel.GetProfileAsync(battletagName, battletagCode, localization);
        }

        #endregion

        #region GetHero

        /// <summary>
        /// 
        /// </summary>
        /// <param name="battletagName"></param>
        /// <param name="battletagCode"></param>
        /// <param name="heroId"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        Hero ID3Service.GetHero(string battletagName, string battletagCode, string heroId, string localization)
        {
            return base.Channel.GetHero(battletagName, battletagCode, heroId, localization);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="battletagName"></param>
        /// <param name="battletagCode"></param>
        /// <param name="heroId"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        Task<Hero> ID3Service.GetHeroAsync(string battletagName, string battletagCode, string heroId, string localization)
        {
            return base.Channel.GetHeroAsync(battletagName, battletagCode, heroId, localization);
        }

        #endregion

        #region GetItem

        /// <summary>
        /// 
        /// </summary>
        /// <param name="itemData"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        ItemInformation ID3Service.GetItemInformation(string itemData, string localization)
        {
            return base.Channel.GetItemInformation(itemData, localization);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="itemData"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        Task<ItemInformation> ID3Service.GetItemInformationAsync(string itemData, string localization)
        {
            return base.Channel.GetItemInformationAsync(itemData, localization);
        }

        #endregion

        #region GetFollower

        /// <summary>
        /// 
        /// </summary>
        /// <param name="followerType"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        FollowerInformation ID3Service.GetFollowerInformation(string followerType, string localization)
        {
            return base.Channel.GetFollowerInformation(followerType, localization);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="followerType"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        Task<FollowerInformation> ID3Service.GetFollowerInformationAsync(string followerType, string localization)
        {
            return base.Channel.GetFollowerInformationAsync(followerType, localization);
        }

        #endregion

        #region GetArtisan

        /// <summary>
        /// 
        /// </summary>
        /// <param name="artisanType"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        ArtisanInformation ID3Service.GetArtisanInformation(string artisanType, string localization)
        {
            return base.Channel.GetArtisanInformation(artisanType, localization);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="artisanType"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        Task<ArtisanInformation> ID3Service.GetArtisanInformationAsync(string artisanType, string localization)
        {
            return base.Channel.GetArtisanInformationAsync(artisanType, localization);
        }

        #endregion

        #endregion

        #region Service Functions

        #region GetProfile

        /// <summary>
        /// 
        /// </summary>
        /// <param name="battletagName"></param>
        /// <param name="battletagCode"></param>
        /// <returns></returns>
        public Profile GetProfile(string battletagName, long battletagCode)
        {
            return ((ID3Service)this).GetProfile(battletagName, battletagCode.ToString(), this._localization.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="battletagName"></param>
        /// <param name="battletagCode"></param>
        /// <returns></returns>
        public Task<Profile> GetProfileAsync(string battletagName, long battletagCode)
        {
            return ((ID3Service)this).GetProfileAsync(battletagName, battletagCode.ToString(), this._localization.ToString());
        }

        #endregion

        #region GetHero

        /// <summary>
        /// 
        /// </summary>
        /// <param name="battletagName"></param>
        /// <param name="battletagCode"></param>
        /// <param name="heroId"></param>
        /// <returns></returns>
        public Hero GetHero(string battletagName, long battletagCode, long heroId)
        {
            return ((ID3Service)this).GetHero(battletagName, battletagCode.ToString(), heroId.ToString(), this._localization.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="battletagName"></param>
        /// <param name="battletagCode"></param>
        /// <param name="heroId"></param>
        /// <returns></returns>
        public Task<Hero> GetHeroAsync(string battletagName, long battletagCode, long heroId)
        {
            return ((ID3Service)this).GetHeroAsync(battletagName, battletagCode.ToString(), heroId.ToString(), this._localization.ToString());
        }

        #endregion

        #region GetItem

        /// <summary>
        /// 
        /// </summary>
        /// <param name="itemData"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        public ItemInformation GetItemInformation(string itemData)
        {
            return ((ID3Service)this).GetItemInformation(itemData, this._localization.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="itemData"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        public Task<ItemInformation> GetItemInformationAsync(string itemData)
        {
            return ((ID3Service)this).GetItemInformationAsync(itemData, this._localization.ToString());
        }

        #endregion

        #region GetFollower

        /// <summary>
        /// 
        /// </summary>
        /// <param name="followerType"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        public FollowerInformation GetFollowerInformation(FollowerTypes followerType)
        {
            return ((ID3Service)this).GetFollowerInformation(followerType.ToString(), this._localization.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="followerType"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        public Task<FollowerInformation> GetFollowerInformationAsync(FollowerTypes followerType)
        {
            return ((ID3Service)this).GetFollowerInformationAsync(followerType.ToString(), this._localization.ToString());
        }

        #endregion

        #region GetArtisan

        /// <summary>
        /// 
        /// </summary>
        /// <param name="artisanType"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        public ArtisanInformation GetArtisanInformation(ArtisanTypes artisanType)
        {
            return ((ID3Service)this).GetArtisanInformation(artisanType.ToString(), this._localization.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="artisanType"></param>
        /// <param name="localization"></param>
        /// <returns></returns>
        public Task<ArtisanInformation> GetArtisanInformationAsync(ArtisanTypes artisanType)
        {
            return ((ID3Service)this).GetArtisanInformationAsync(artisanType.ToString(), this._localization.ToString());
        }

        #endregion

        #endregion
    }
}
